package com.example.back.service;

import com.example.back.dto.LoginRequest;
import com.example.back.dto.LoginResponse;
import com.example.back.dto.RegisterRequest;
import com.example.back.dto.UserResponse;
import com.example.back.entity.User;
import com.example.back.repository.UserRepository;
import com.example.back.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 用户服务层
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserService {
    
    private final UserRepository userRepository;
    private final JwtUtil jwtUtil;
    
    /**
     * 用户注册
     */
    @Transactional
    public UserResponse register(RegisterRequest request) {
        log.info("用户注册: {}", request.getUsername());
        
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(request.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (request.getEmail() != null && userRepository.existsByEmail(request.getEmail())) {
            throw new RuntimeException("邮箱已被使用");
        }
        
        // 创建用户
        User user = new User();
        user.setUsername(request.getUsername());
        // 注意：生产环境中应该使用密码加密（BCrypt等）
        user.setPassword(encodePassword(request.getPassword()));
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setNickname(request.getNickname() != null ? request.getNickname() : request.getUsername());
        user.setWalletAddress(request.getWalletAddress());
        user.setStatus(0); // 0-正常
        
        User savedUser = userRepository.save(user);
        log.info("用户注册成功: {}", savedUser.getId());
        
        return UserResponse.fromEntity(savedUser);
    }
    
    /**
     * 用户登录
     */
    public LoginResponse login(LoginRequest request) {
        log.info("用户登录: {}", request.getUsername());
        
        // 查找用户
        User user = userRepository.findByUsername(request.getUsername())
                .orElseThrow(() -> new RuntimeException("用户名或密码错误"));
        
        // 验证密码
        if (!verifyPassword(request.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 检查用户状态
        if (user.getStatus() == 1) {
            throw new RuntimeException("账号已被禁用");
        }
        
        // 生成JWT Token
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        claims.put("email", user.getEmail());
        String token = jwtUtil.generateToken(user.getUsername(), claims);
        
        log.info("用户登录成功: {}", user.getId());
        
        return new LoginResponse(token, UserResponse.fromEntity(user));
    }
    
    /**
     * 根据ID获取用户信息
     */
    public UserResponse getUserById(Long id) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        return UserResponse.fromEntity(user);
    }
    
    /**
     * 根据用户名获取用户信息
     */
    public UserResponse getUserByUsername(String username) {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        return UserResponse.fromEntity(user);
    }
    
    /**
     * 更新用户信息
     */
    @Transactional
    public UserResponse updateUser(Long id, RegisterRequest request) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 更新允许修改的字段
        if (request.getEmail() != null) {
            user.setEmail(request.getEmail());
        }
        if (request.getPhone() != null) {
            user.setPhone(request.getPhone());
        }
        if (request.getNickname() != null) {
            user.setNickname(request.getNickname());
        }
        
        // 钱包地址特殊处理
        if (request.getWalletAddress() != null) {
            // 如果是解绑（设置为null）
            if (request.getWalletAddress().trim().isEmpty() || "null".equalsIgnoreCase(request.getWalletAddress())) {
                user.setWalletAddress(null);
            } else {
                // 绑定新钱包
                String newWalletAddress = request.getWalletAddress().toLowerCase();
                
                // 检查该钱包是否已被其他用户绑定
                Optional<User> existingUser = userRepository.findByWalletAddress(newWalletAddress);
                if (existingUser.isPresent() && !existingUser.get().getId().equals(id)) {
                    throw new RuntimeException("该钱包地址已被其他用户绑定");
                }
                
                // 如果用户已经绑定了钱包，不允许更改（一个用户只能绑定一个钱包）
                if (user.getWalletAddress() != null && !user.getWalletAddress().isEmpty()) {
                    throw new RuntimeException("已绑定钱包，不能修改。请先解绑再绑定新钱包");
                }
                
                user.setWalletAddress(newWalletAddress);
            }
        }
        
        User updatedUser = userRepository.save(user);
        return UserResponse.fromEntity(updatedUser);
    }
    
    /**
     * 密码加密（简单实现，生产环境建议使用BCrypt）
     */
    private String encodePassword(String password) {
        // 这里为了简单使用Base64，生产环境应该使用BCrypt
        // return new BCryptPasswordEncoder().encode(password);
        return java.util.Base64.getEncoder().encodeToString(password.getBytes());
    }
    
    /**
     * 密码验证
     */
    private boolean verifyPassword(String rawPassword, String encodedPassword) {
        String encoded = encodePassword(rawPassword);
        return encoded.equals(encodedPassword);
    }
}

